﻿using System;
using System.IO;
using System.Text;
using Zo.Logging;
using Zo.Tasks;

namespace Zo.Logging
{
    internal class TxtLogMonoConcurrentTask : MonoConcurrentTaskBase
    {
        private static readonly object _lockObject = new object();

        protected override void OnExecute(object currentTask)
        {
            if (currentTask == null)
            {
                return;
            }

            if (currentTask is TxtLogDTO)
            {
                var txt = (TxtLogDTO)(currentTask);

                WriteLog(txt);
            }
        }

        private void WriteLog(TxtLogDTO logDTO)
        {
            try
            {
                var message = logDTO.Message;

                //生成目录路径。
                var directory = Path.Combine(
                    AppDomain.CurrentDomain.BaseDirectory,
                    "logs",
                    logDTO.LogType ?? string.Empty,
                    DateTime.Now.ToString("yyyy"),
                    DateTime.Now.ToString("MM"),
                    DateTime.Now.ToString("dd"));

                //获取当前系统时间。
                var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");

                var fileNameBuilder = new StringBuilder();

                fileNameBuilder.Append(directory);
                fileNameBuilder.Append("/");

                if (!string.IsNullOrWhiteSpace(logDTO.FunctionType))
                {
                    fileNameBuilder.Append(logDTO.FunctionType);
                    fileNameBuilder.Append("_");
                }

                fileNameBuilder.Append(DateTime.Now.ToString("yyyyMMdd"));
                fileNameBuilder.Append(".log");

                //用日期对日志文件命名。
                var filename = fileNameBuilder.ToString();

                WirteFile(directory, filename, $"{message}");
            }
            catch { }
        }

        private void WirteFile(string directory, string path, string message)
        {
            try
            {
                //如果日志目录不存在就创建。
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                lock (_lockObject)
                {
                    using (var streamWriter = File.AppendText(path))
                    {
                        streamWriter.WriteLine(message);
                        streamWriter.Flush();
                    }
                }
            }
            catch (Exception exception)
            {
                path = $"{directory}/{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.error";

                var errorBuilder = new StringBuilder();

                errorBuilder.AppendLine($"写入日志：{message} 过程中出现异常");
                errorBuilder.AppendLine(exception.Message);
                errorBuilder.AppendLine(exception.StackTrace);

                lock (_lockObject)
                {
                    using (var streamWriter = File.AppendText(path))
                    {
                        streamWriter.WriteLine(errorBuilder.ToString());
                        streamWriter.Flush();
                    }
                }
            }
        }
    }
}